package client.gui;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.GridBagLayout;
import javax.swing.JRadioButton;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.JComboBox;

import javax.swing.ButtonGroup;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JList;
import javax.swing.ListSelectionModel;

import client.TcpClient;
import client.gui.util.Side;
import client.gui.util.Ticket;


import util.ClientProtocol;
import util.MessageCreator;

@SuppressWarnings("serial")
public class ClientGUI extends JFrame {
	
	private JPanel contentPane = new JPanel();
	private final ButtonGroup sideGroup = new ButtonGroup();
	private final ButtonGroup typeGroup = new ButtonGroup();
	private JTextField priceField;
	private JTextField amountField;
	private JComboBox<Ticket> ticketBox;
	private JList<String> infoList;
	private JList<String> orderList;
	private JLabel nameLabel;
	private JButton sendOrderBtn;
	
	private TcpClient tc;
	
	client.gui.util.Side sideOption = client.gui.util.Side.S;
	client.gui.util.Type typeOption = client.gui.util.Type.L;
	double priceOption;
	int amountOption;

	/**
	 * Create the frame.
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public ClientGUI(final TcpClient tc) {
		this.tc = tc;
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		GridBagLayout gbl_contentPane = new GridBagLayout();
		gbl_contentPane.columnWidths = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
		gbl_contentPane.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
		gbl_contentPane.columnWeights = new double[]{0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};
		gbl_contentPane.rowWeights = new double[]{0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};
		contentPane.setLayout(gbl_contentPane);
		
		nameLabel = new JLabel("Welcome: " + tc.getClient().getName());
		GridBagConstraints gbc_nameLabel = new GridBagConstraints();
		gbc_nameLabel.insets = new Insets(0, 0, 5, 5);
		gbc_nameLabel.gridx = 0;
		gbc_nameLabel.gridy = 0;
		contentPane.add(nameLabel, gbc_nameLabel);
		
		JPanel newOrderPanel = new JPanel();
		GridBagConstraints gbc_newOrderPanel = new GridBagConstraints();
		gbc_newOrderPanel.gridheight = 8;
		gbc_newOrderPanel.insets = new Insets(0, 0, 0, 5);
		gbc_newOrderPanel.fill = GridBagConstraints.BOTH;
		gbc_newOrderPanel.gridx = 0;
		gbc_newOrderPanel.gridy = 1;
		contentPane.add(newOrderPanel, gbc_newOrderPanel);
		GridBagLayout gbl_newOrderPanel = new GridBagLayout();
		gbl_newOrderPanel.columnWidths = new int[]{0, 0, 0};
		gbl_newOrderPanel.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
		gbl_newOrderPanel.columnWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
		gbl_newOrderPanel.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		newOrderPanel.setLayout(gbl_newOrderPanel);
		
		sendOrderBtn = new JButton("new Order");
		sendOrderBtn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				tc.sendMessage(MessageCreator.newOrderMessage(TcpClient.clientReferenceId++,(Ticket)ticketBox.getSelectedItem(),
						typeOption,sideOption,amountField.getText(),priceField.getText()));
			}
		});
		
		JRadioButton rdbtnLimit = new JRadioButton("Limit");
		rdbtnLimit.doClick();
		rdbtnLimit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				typeOption = client.gui.util.Type.L;
			}
		});
		
		JRadioButton rdbtnBuy = new JRadioButton("Buy");
		rdbtnBuy.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				sideOption = Side.B;
			}
		});
		
		JRadioButton rdbtnSell = new JRadioButton("Sell");
		rdbtnSell.doClick();
		rdbtnSell.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				sideOption = Side.S;
			}
		});
		GridBagConstraints gbc_rdbtnSell = new GridBagConstraints();
		gbc_rdbtnSell.insets = new Insets(0, 0, 5, 5);
		gbc_rdbtnSell.gridx = 0;
		gbc_rdbtnSell.gridy = 1;
		newOrderPanel.add(rdbtnSell, gbc_rdbtnSell);
		sideGroup.add(rdbtnSell);
		GridBagConstraints gbc_rdbtnBuy = new GridBagConstraints();
		gbc_rdbtnBuy.insets = new Insets(0, 0, 5, 0);
		gbc_rdbtnBuy.gridx = 1;
		gbc_rdbtnBuy.gridy = 1;
		newOrderPanel.add(rdbtnBuy, gbc_rdbtnBuy);
		sideGroup.add(rdbtnBuy);
		GridBagConstraints gbc_rdbtnLimit = new GridBagConstraints();
		gbc_rdbtnLimit.insets = new Insets(0, 0, 5, 5);
		gbc_rdbtnLimit.gridx = 0;
		gbc_rdbtnLimit.gridy = 2;
		newOrderPanel.add(rdbtnLimit, gbc_rdbtnLimit);
		typeGroup.add(rdbtnLimit);
		
		JRadioButton rdbtnMarket = new JRadioButton("Market");
		rdbtnMarket.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				typeOption = client.gui.util.Type.M;
			}
		});
		GridBagConstraints gbc_rdbtnMarket = new GridBagConstraints();
		gbc_rdbtnMarket.insets = new Insets(0, 0, 5, 0);
		gbc_rdbtnMarket.gridx = 1;
		gbc_rdbtnMarket.gridy = 2;
		newOrderPanel.add(rdbtnMarket, gbc_rdbtnMarket);
		typeGroup.add(rdbtnMarket);
		
		ticketBox = new JComboBox(Ticket.values());
		GridBagConstraints gbc_ticketBox = new GridBagConstraints();
		gbc_ticketBox.fill = GridBagConstraints.HORIZONTAL;
		gbc_ticketBox.gridwidth = 2;
		gbc_ticketBox.insets = new Insets(0, 0, 5, 0);
		gbc_ticketBox.gridx = 0;
		gbc_ticketBox.gridy = 3;
		newOrderPanel.add(ticketBox, gbc_ticketBox);
		
		JLabel lblPrice = new JLabel("Price");
		GridBagConstraints gbc_lblPrice = new GridBagConstraints();
		gbc_lblPrice.insets = new Insets(0, 0, 5, 5);
		gbc_lblPrice.gridx = 0;
		gbc_lblPrice.gridy = 4;
		newOrderPanel.add(lblPrice, gbc_lblPrice);
		
		priceField = new JTextField();
		GridBagConstraints gbc_priceField = new GridBagConstraints();
		gbc_priceField.fill = GridBagConstraints.HORIZONTAL;
		gbc_priceField.gridwidth = 2;
		gbc_priceField.insets = new Insets(0, 0, 5, 0);
		gbc_priceField.gridx = 0;
		gbc_priceField.gridy = 5;
		newOrderPanel.add(priceField, gbc_priceField);
		priceField.setColumns(10);
		
		JLabel lblAmount = new JLabel("Amount");
		GridBagConstraints gbc_lblAmount = new GridBagConstraints();
		gbc_lblAmount.insets = new Insets(0, 0, 5, 5);
		gbc_lblAmount.gridx = 0;
		gbc_lblAmount.gridy = 6;
		newOrderPanel.add(lblAmount, gbc_lblAmount);
		
		amountField = new JTextField();
		GridBagConstraints gbc_amountField = new GridBagConstraints();
		gbc_amountField.fill = GridBagConstraints.HORIZONTAL;
		gbc_amountField.gridwidth = 2;
		gbc_amountField.insets = new Insets(0, 0, 5, 0);
		gbc_amountField.gridx = 0;
		gbc_amountField.gridy = 7;
		newOrderPanel.add(amountField, gbc_amountField);
		amountField.setColumns(10);
		GridBagConstraints gbc_sendOrderBtn = new GridBagConstraints();
		gbc_sendOrderBtn.insets = new Insets(0, 0, 5, 0);
		gbc_sendOrderBtn.fill = GridBagConstraints.HORIZONTAL;
		gbc_sendOrderBtn.gridwidth = 2;
		gbc_sendOrderBtn.gridx = 0;
		gbc_sendOrderBtn.gridy = 8;
		newOrderPanel.add(sendOrderBtn, gbc_sendOrderBtn);
		
		JScrollPane orderPanel = new JScrollPane();
		GridBagConstraints gbc_orderPanel = new GridBagConstraints();
		gbc_orderPanel.gridwidth = 5;
		gbc_orderPanel.gridheight = 3;
		gbc_orderPanel.insets = new Insets(0, 0, 5, 5);
		gbc_orderPanel.fill = GridBagConstraints.BOTH;
		gbc_orderPanel.gridx = 1;
		gbc_orderPanel.gridy = 1;
		contentPane.add(orderPanel, gbc_orderPanel);
		
		orderList = new JList<String>(tc.getGuiChanger().getOrderModel());
		orderPanel.setViewportView(orderList);
		
		JScrollPane orderBookPanel = new JScrollPane();
		GridBagConstraints gbc_orderBookPanel = new GridBagConstraints();
		gbc_orderBookPanel.gridwidth = 4;
		gbc_orderBookPanel.gridheight = 4;
		gbc_orderBookPanel.insets = new Insets(0, 0, 5, 0);
		gbc_orderBookPanel.fill = GridBagConstraints.BOTH;
		gbc_orderBookPanel.gridx = 6;
		gbc_orderBookPanel.gridy = 1;
		contentPane.add(orderBookPanel, gbc_orderBookPanel);
		
		JButton cancelOrderBtn = new JButton("cancel Order");
		GridBagConstraints gbc_cancelOrderBtn = new GridBagConstraints();
		gbc_cancelOrderBtn.gridwidth = 2;
		gbc_cancelOrderBtn.insets = new Insets(0, 0, 5, 5);
		gbc_cancelOrderBtn.gridx = 1;
		gbc_cancelOrderBtn.gridy = 4;
		contentPane.add(cancelOrderBtn, gbc_cancelOrderBtn);
		cancelOrderBtn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if(orderList.getSelectedValue() != null) {
					Pattern pattern = Pattern.compile(ClientProtocol.ORDERLIST_ELEMENT_MATCHER);
					Matcher matcher = pattern.matcher(orderList.getSelectedValue());
					if(matcher.find()) {
						tc.sendMessage(MessageCreator.cancelMessage(matcher.group(1)));					
					}
				}
			}
		});
		
		JScrollPane infoPanel = new JScrollPane();
		GridBagConstraints gbc_infoPanel = new GridBagConstraints();
		gbc_infoPanel.gridheight = 4;
		gbc_infoPanel.gridwidth = 9;
		gbc_infoPanel.fill = GridBagConstraints.BOTH;
		gbc_infoPanel.gridx = 1;
		gbc_infoPanel.gridy = 5;
		contentPane.add(infoPanel, gbc_infoPanel); 
		infoList = new JList<String>(tc.getGuiChanger().getListModel());
		infoList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		infoPanel.setViewportView(infoList);
	}
	
	public TcpClient getTc() {
		return tc;
	}
	
}
